/*
 * boundedbuffer.c
 *
 *  Created on: Apr 10, 2011
 *      Author: xozyain
 */
#include "types.h"
#include "user.h"
#include "boundedbuffer.h"

struct BB * BB_create(int max_capacity){
	struct BB * bb;

	if (!(bb = (struct BB *)malloc(sizeof(struct BB)))){
		printf(2,"boundedbuffer: BB_create: malloc error\n");
		exit();
	}
	bb->_max_capacity = max_capacity;
	bb->bufferList = (Lnk *)0;
	bb->empty = semaphore_create(max_capacity);
	bb->full = semaphore_create(0);
	bb->mutex = binary_sem_create();
	bb->count=0;
	bb->last = 0;

	return bb;

}


void semaphore_put(struct BB* bb, void * element){
	Lnk * tmp;

	sem_down(bb->empty);
	if (binary_sem_down(bb->mutex)<0){
		printf(2,"BB: semaphore_put: binary_sem_down: ERROR\n");
		exit();
	}

	if (!(tmp = (Lnk*)malloc(sizeof(Lnk)))){
		printf(2,"BB: semaphore_put: MALLOC ERROR\n");
		exit();
	}

	tmp->element = element;

	tmp->next=0;
	if(bb->bufferList == 0){
		bb->bufferList = tmp;
		bb->last = tmp;
	}
	else{
		bb->last->next=tmp;
		bb->last = bb->last->next;
	}

	bb->count++; //for debug

	if (binary_sem_up(bb->mutex)<0){
		printf(2,"BB: semaphore_put: binary_sem_up: ERROR\n");
		exit();
	}
	sem_up(bb->full);

}

void * semaphore_pop(struct BB* bb){
	Lnk * ans;
	void * elem;


	sem_down(bb->full);
	if (binary_sem_down(bb->mutex)<0){
		printf(2,"BB: semaphore_pop: binary_sem_down: ERROR\n");
		exit();
	}

	// FIFO order
	ans = bb->bufferList->next;
	elem = bb->bufferList->element;
	bb->bufferList = ans;
	bb->count--;


	if (binary_sem_up(bb->mutex)<0){
		printf(2,"BB: semaphore_pop: binary_sem_up: ERROR\n");
		exit();
	}
	sem_up(bb->empty);

	return elem;
}
